package ywu.pocket;

import android.content.*;
import android.app.*;
import android.os.*;
import android.util.*;
import android.hardware.*;

public class PocketModeService extends Service implements SensorEventListener {
    private static final String TAG = "YwuPocket";

    private SensorManager sensorMgr;
    private Sensor lightSensor, proximitySensor;

    private float currLight, currDistance;
    private boolean inPocket;

    static {
        System.loadLibrary("sensor_helper");
    }

    @Override
    public IBinder onBind(final Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
        lightSensor = sensorMgr.getDefaultSensor(Sensor.TYPE_LIGHT);
        proximitySensor = sensorMgr.getDefaultSensor(Sensor.TYPE_PROXIMITY);

        dumpSensor(lightSensor);
        dumpSensor(proximitySensor);

        //sensorMgr.registerListener(this, lightSensor, SensorManager.SENSOR_DELAY_FASTEST);
        sensorMgr.registerListener(this, proximitySensor, SensorManager.SENSOR_DELAY_FASTEST);

        new Thread(new Runnable() {
            public void run() {
                startMonitoring();
            }
        }).start();
    }

    @Override
    public void onAccuracyChanged(final Sensor s, final int accuracy) {
        Log.d(TAG, String.format("accuracyChanged, sensor=%s, accuracy=%d", s.getName(), accuracy));
    }

    @Override
    public void onSensorChanged(final SensorEvent e) {
        Sensor s = e.sensor;
        int accuracy = e.accuracy;
        float[] values = e.values;
        Log.d(TAG, String.format("sensorChanged, sensor=%s, accuracy=%d", s.getName(), accuracy));

        if (s == lightSensor) {
            currLight = values[0];
            Log.d(TAG, String.format("light => %f lx", currLight));
        }
        else if (s == proximitySensor) {
            currDistance = values[0];
            Log.d(TAG, String.format("distance => %f cm", currDistance));
        }

        updateState();
    }

    private void updateState() {
        boolean oldState = inPocket;
        inPocket = currDistance <= 1 && currLight <= 10;
        boolean stateChanged = oldState != inPocket;

        if (stateChanged) {
            Log.i(TAG, String.format("pocket state changed: %s ==> %s", oldState, inPocket));
            notifyStateChanged(inPocket, oldState);
        }
    }

    private void notifyStateChanged(final boolean newState, final boolean oldState) {
        ((Vibrator) getSystemService(VIBRATOR_SERVICE)).vibrate(newState ? new long[] { 0, 200, 100, 200 } : new long[] { 0, 200 }, -1); 
    }

    private static void dumpSensor(final Sensor s) {
        StringBuilder buf = new StringBuilder(s.getName());
        buf.append(", resolution=").append(s.getResolution()).append(", power=").append(s.getPower());
        buf.append(", maxRange=").append(s.getMaximumRange()).append(", minDelay=").append(s.getMinDelay());
        Log.d(TAG, buf.toString());
    }

    private native static void startMonitoring();
}